package org.test4j.mock.faking.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

public class ObjectIdentify {
    /**
     * 如果对象为null表示没有匹配的实例，设置为0
     *
     * @param objects
     * @return
     */
    public static Integer[] identities(Object[] objects) {
        if (objects == null) {
            return new Integer[]{0};
        } else if (objects.length == 0) {
            return new Integer[0];
        }
        if (objects.length == 1) {
            if (objects[0] instanceof Collection) {
                return identities((Collection) objects[0]);
            } else {
                return new Integer[]{identityObj(objects[0])};
            }
        } else {
            return Arrays.stream(objects)
                .map(ObjectIdentify::identityObj)
                .collect(Collectors.toList())
                .toArray(new Integer[0]);
        }
    }

    private static Integer[] identities(Collection objects) {
        if (objects.size() == 0) {
            return new Integer[]{-1};
        }
        List<Integer> list = new ArrayList<>();
        for (Object obj : objects) {
            if (obj instanceof Integer) {
                list.add((Integer) obj);
            } else {
                list.add(System.identityHashCode(obj));
            }
        }
        return list.toArray(new Integer[0]);
    }

    public static Integer[] identity(Class declaredClass, Collection list) {
        List<Integer> hashCodes = new ArrayList<>();
        if (list == null) {
        } else if (declaredClass.isAssignableFrom(list.getClass())) {
            hashCodes.add(System.identityHashCode(list));
        } else {
            list.stream().map(ObjectIdentify::identityObj)
                .forEach(i -> hashCodes.add((Integer) i));
        }
        return hashCodes.toArray(new Integer[0]);
    }

    public static Class getObjectClass(Object[] objects) {
        if (objects == null || objects.length == 0 || objects[0] == null) {
            throw new RuntimeException("the object can't be null.");
        } else if (objects.length == 1 && objects[0] instanceof Collection) {
            return getObjectClass((Collection) objects[0]);
        } else {
            return objects[0].getClass();
        }
    }

    public static Class getObjectClass(Collection objects) {
        if (objects == null || objects.size() == 0) {
            throw new RuntimeException("the object can't be null.");
        }
        Object first = objects.iterator().next();
        if (first == null) {
            throw new RuntimeException("the object can't be null.");
        } else {
            return first.getClass();
        }
    }

    /**
     * 返回对象列表的内存地址列表
     *
     * @param target
     * @return
     */
    private static Integer identityObj(Object target) {
        if (target instanceof Integer) {
            return (Integer) target;
        } else {
            return System.identityHashCode(target);
        }
    }
}
